package com.paic.mhis.hcpms.assessment.biz.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.paic.mhis.common.base.intergration.dao.CommonDAO;
import com.paic.mhis.core.auth.biz.service.UserDetails;
import com.paic.mhis.core.user.dto.RegionDTO;
import com.paic.mhis.hcpms.assessment.biz.service.AssessmentIndicatorService;
import com.paic.mhis.hcpms.assessment.dto.IndicaotrSourceDTO;
import com.paic.mhis.hcpms.assessment.dto.IndicatorConfigDetailDTO;
import com.paic.mhis.hcpms.assessment.dto.IndicatorConfigInfoDTO;
import com.paic.mhis.hcpms.assessment.dto.IndicatorConfigParamsDTO;
import com.paic.mhis.hcpms.assessment.dto.IndicatorConfigTreeDTO;
import com.paic.mhis.hcpms.assessment.dto.IndicatorHomeInfoDTO;
import com.paic.mhis.hcpms.assessment.dto.IndicatorScore;
import com.paic.mhis.hcpms.assessment.intergration.dao.AssessmentIndicatorDAO;
import com.paic.mhis.hcpms.common.community.biz.service.NormalDistributionService;
import com.paic.mhis.hcpms.common.community.dto.ConfidenceIntervalDTO;
import com.paic.mhis.hcpms.quota.indicatorconfig.intergration.dao.IndicatorConfigDAO;

/**
 * 
 * @author EX-CAOTIANHUA001
 * 
 */
@Service("assessmentIndicatorService")
public class AssessmentIndicatorServiceImpl implements AssessmentIndicatorService {

	@Autowired
	private AssessmentIndicatorDAO assessmentIndicatorDAO;

	@Autowired
	private NormalDistributionService normalDistributionService;

	@Autowired
	private CommonDAO commonDAO;

	@Autowired
	public IndicatorConfigDAO indicatorConfigDao;

	@Override
	public List<IndicatorHomeInfoDTO> queryIndicatorHomePage(String regionCode) {
		return assessmentIndicatorDAO.queryIndicatorHomePage(regionCode, null);
	}

	@Override
	public List<IndicatorConfigTreeDTO> queryIndicatorHomeTree(String userName) {
		// 获取所有的统筹区域
		List<RegionDTO> regionDtos = indicatorConfigDao.queryRegionByUserName(userName);
		List<IndicatorConfigTreeDTO> treeDtos = new ArrayList<IndicatorConfigTreeDTO>();
		for (RegionDTO regionDto : regionDtos) {
			IndicatorConfigTreeDTO treeDto = new IndicatorConfigTreeDTO();
			treeDto.setText(regionDto.getName());
			treeDto.setRegionCode(regionDto.getCode());
			List<IndicatorConfigTreeDTO> dtos = new ArrayList<IndicatorConfigTreeDTO>();

			List<IndicatorHomeInfoDTO> baseDtos = assessmentIndicatorDAO.queryIndicatorHomePage(regionDto.getCode(),
					null);

			for (IndicatorHomeInfoDTO baseDto : baseDtos) {
				IndicatorConfigTreeDTO dto = new IndicatorConfigTreeDTO();
				dto.setText(baseDto.getText());
				dto.setRegionCode(regionDto.getCode());
				dto.setIndicatorCode(baseDto.getIndicatorCodeT());
				dtos.add(dto);
			}
			if (null != dtos && dtos.size() > 0) {
				treeDto.setNodes(dtos);
			}
			treeDtos.add(treeDto);
		}
		return treeDtos;
	}

	@Override
	public IndicatorConfigInfoDTO getIndicatorConfig(String indicatorCode, String regionCode, String orgLevel) {
		List<IndicatorConfigInfoDTO> rlis = assessmentIndicatorDAO.queryEachIndicatorInfo(indicatorCode, orgLevel,
				regionCode);
		if (rlis != null && rlis.size() == 1) {
			return rlis.get(0);
		}
		return new IndicatorConfigInfoDTO();
	}

	@Override
	public List<IndicatorConfigInfoDTO> getIndicatorConfig(String indicatorCode, String regionCode) {
		return assessmentIndicatorDAO.queryEachIndicatorInfo(indicatorCode, null, regionCode);
	}

	@Override
	public List<IndicaotrSourceDTO> getIndicatorScore(List<IndicaotrSourceDTO> sample, List<IndicaotrSourceDTO> target,
			String indicatorCode, String prividerLevle, String regionCode, String kpiTime) {

		IndicatorConfigInfoDTO icd = getIndicatorConfig(indicatorCode, regionCode, prividerLevle);
		// 未启用
		if ("1".equals(icd.getIsEnable()) || null == icd.getIsEnable()) {
			return target;
		}

		List<Double> nums = new ArrayList<Double>();
		// 横向对比 对象范围不为本机构

		BigDecimal per = icd.getValue();
		BigDecimal embroiValue = icd.getEmbroiValue();
		if ("1".equals(icd.getEvaluationMethod()) && !"3".equals(icd.getCompareRange())) {

			for (IndicaotrSourceDTO isd : sample) {
				double tempNum = isd.getIndicator_value();
				nums.add(tempNum);
			}
			ConfidenceIntervalDTO cid = normalDistributionService.getConfidenceInterval(nums, per.doubleValue() / 100);
			for (IndicaotrSourceDTO isd : target) {
				double tempNum = isd.getIndicator_value();
				int score = getCurrentScore(nums, tempNum, per.doubleValue() / 100, embroiValue.doubleValue() / 100);
				IndicatorScore is = new IndicatorScore();
				is.setScore(score);
				is.setLower_limit(cid.getX());
				is.setUpper_limit(cid.getY());
				isd.setIndicatorScore(is);
			}
		}
		// 横向对比 对象范围为本机构
		else if ("1".equals(icd.getEvaluationMethod()) && "3".equals(icd.getCompareRange())) {
			for (IndicaotrSourceDTO isd : target) {
				IndicatorScore indicatorScore = getCurrentProviderScore(sample, isd, per.doubleValue() / 100,
						embroiValue.doubleValue() / 100);
				isd.setIndicatorScore(indicatorScore);
			}
		}
		// 绝对值1
		else if ("2".equals(icd.getEvaluationMethod())) {
			for (IndicaotrSourceDTO isd : target) {
				// kpi得分
				double tempNum = isd.getIndicator_value();

				// 阈值范围
				int thresholdValue = (int) (icd.getValue().doubleValue());
				IndicatorScore is = new IndicatorScore();
				// 大于阈值得满分
				if ((int) tempNum >= thresholdValue) {
					is.setScore(100);
				} else {
					is.setScore((int) (tempNum / thresholdValue * 100));
				}
				is.setLower_limit(thresholdValue);
				is.setUpper_limit(100);
				isd.setIndicatorScore(is);
			}
		}
		// 绝对值2
		else if ("3".equals(icd.getEvaluationMethod())) {
			for (IndicaotrSourceDTO isd : target) {
				IndicatorScore is = new IndicatorScore();
				if (icd.getValue().doubleValue() == 1.0) {
					is.setScore(100);
				} else {
					is.setScore(0);
				}

				isd.setIndicatorScore(is);
			}
		}

		return target;
	}

	private IndicatorScore getCurrentProviderScore(List<IndicaotrSourceDTO> sample, IndicaotrSourceDTO isd, double per,
			double embroiValue) {
		List<Double> nums = new ArrayList<Double>();
		IndicatorScore indicatorScore = new IndicatorScore();
		double targetValue = isd.getIndicator_value();
		for (IndicaotrSourceDTO temp : sample) {
			if (temp.getProvider_code().equals(isd.getProvider_code())) {
				double tempNum = temp.getIndicator_value();
				nums.add(tempNum);
			}
		}
		ConfidenceIntervalDTO cid = normalDistributionService.getConfidenceInterval(nums, per);
		int score = getCurrentScore(nums, targetValue, per, embroiValue);
		indicatorScore.setScore(score);
		indicatorScore.setLower_limit(cid.getX());
		indicatorScore.setUpper_limit(cid.getY());
		return indicatorScore;
	}

	private int getCurrentScore(List<Double> nums, double tempNum, double per, double embroiValue) {

		double fullPer = per;
		int resultScore = 0;
		for (int i = (int) (per * 100); i < 100; i++) {
			ConfidenceIntervalDTO cid = normalDistributionService.getConfidenceInterval(nums, i / 100.00);
			int tempScore = 100 - (int) (embroiValue * 100) * (int) (i - fullPer * 100);
			if (tempNum > cid.getX() && tempNum < cid.getY()) {
				resultScore = tempScore;
				break;
			}
		}

		return resultScore;
	}

	@Override
	public Map<String, Object> saveIndicatorConfig(List<IndicatorConfigInfoDTO> lisDto) {
		Map<String, Object> param = null;
		if (lisDto != null && lisDto.size() > 0) {
			param = new HashMap<String, Object>();
			for (IndicatorConfigInfoDTO dto : lisDto) {
				if (dto.getIsValid() == null) {
					String uuid = commonDAO.getUUID();
					dto.setIdConfigDetail(uuid);
					IndicatorConfigDetailDTO detailDto = new IndicatorConfigDetailDTO();
					BeanUtils.copyProperties(dto, detailDto);
					assessmentIndicatorDAO.insertConfigDetail(detailDto);
					IndicatorConfigParamsDTO paramDto = new IndicatorConfigParamsDTO();
					BeanUtils.copyProperties(dto, paramDto);
					paramDto.setParamValue(dto.getValue());
					paramDto.setParamValue2(dto.getUnitValue());
					paramDto.setParamValue3(dto.getEmbroiValue());
					assessmentIndicatorDAO.insertStandardParams(paramDto);
				} else {
					if (dto.getIsValid().equals("0")) {
						IndicatorConfigDetailDTO detailDto = new IndicatorConfigDetailDTO();
						BeanUtils.copyProperties(dto, detailDto);

						IndicatorConfigParamsDTO paramDto = new IndicatorConfigParamsDTO();
						BeanUtils.copyProperties(dto, paramDto);
						paramDto.setParamValue(dto.getValue());
						paramDto.setParamValue2(dto.getUnitValue());
						paramDto.setParamValue3(dto.getEmbroiValue());
						assessmentIndicatorDAO.updateStandardParams(paramDto);
					} else if (dto.getIsValid().equals("1")) {
						assessmentIndicatorDAO.deleteConfigDetail(dto.getIndicatorCode(), dto.getOrgLevel(),
								dto.getRegionCode());
					}
				}
			}
			param.put("msg", "更新成功!");
		}

		return param;
	}

	@Override
	public Map<String, Object> saveIndicatorConfig(List<IndicatorConfigInfoDTO> lisDto, UserDetails userDetails) {
		Map<String, Object> param = null;
		String loginUserName = userDetails.getUsername();
		if (lisDto != null && lisDto.size() > 0) {
			param = new HashMap<String, Object>();
			for (IndicatorConfigInfoDTO dto : lisDto) {
				if (dto.getIsEnable() != null && dto.getIsEnable().equals("1")) {
					assessmentIndicatorDAO.deleteConfigDetail(dto.getIndicatorCode(), null, dto.getRegionCode());
					break;
				}
				if (dto.getIsValid() == null) {
					String uuid = commonDAO.getUUID();
					dto.setIdConfigDetail(uuid);
					IndicatorConfigDetailDTO detailDto = new IndicatorConfigDetailDTO();
					BeanUtils.copyProperties(dto, detailDto);
					detailDto.setUpdatedBy(loginUserName);
					detailDto.setCreatedBy(loginUserName);
					assessmentIndicatorDAO.insertConfigDetail(detailDto);
					IndicatorConfigParamsDTO paramDto = new IndicatorConfigParamsDTO();
					BeanUtils.copyProperties(dto, paramDto);
					paramDto.setCreatedBy(loginUserName);
					paramDto.setUpdatedBy(loginUserName);
					paramDto.setIdConfigDetail(uuid);
					paramDto.setParamValue(dto.getValue());
					paramDto.setParamValue2(dto.getUnitValue());
					paramDto.setParamValue3(dto.getEmbroiValue());
					assessmentIndicatorDAO.insertStandardParams(paramDto);
				} else {
					if (dto.getIsValid().equals("0")) {
						IndicatorConfigDetailDTO detailDto = new IndicatorConfigDetailDTO();
						BeanUtils.copyProperties(dto, detailDto);
						detailDto.setCreatedBy(loginUserName);
						detailDto.setUpdatedBy(loginUserName);
						assessmentIndicatorDAO.updateConfigDetail(detailDto);
						IndicatorConfigParamsDTO paramDto = new IndicatorConfigParamsDTO();
						BeanUtils.copyProperties(dto, paramDto);
						paramDto.setParamValue(dto.getValue());
						paramDto.setParamValue2(dto.getUnitValue());
						paramDto.setParamValue3(dto.getEmbroiValue());
						assessmentIndicatorDAO.updateStandardParams(paramDto);
					} else if (dto.getIsValid().equals("1")) {
						assessmentIndicatorDAO.deleteConfigDetail(dto.getIndicatorCode(), dto.getOrgLevel(),
								dto.getRegionCode());
					}
				}
			}
			param.put("msg", "更新成功!");
		}

		return param;
	}

	@Override
	public IndicatorHomeInfoDTO queryIndicatorConfig(String indicatorCode, String regionCode) {
		IndicatorHomeInfoDTO indicatorInfo = null;
		List<IndicatorHomeInfoDTO> hlis = assessmentIndicatorDAO.queryIndicatorHomePage(regionCode, indicatorCode);
		if (hlis.size() == 1) {
			indicatorInfo = hlis.get(0);
			List<IndicatorConfigInfoDTO> lis = assessmentIndicatorDAO.queryEachIndicatorInfo(indicatorCode, null,
					regionCode);
			indicatorInfo.setDetailList(lis);
			if (lis.size() > 0) {
				// 0:启用 ; 1:不启用
				indicatorInfo.setIsEnable("0");
			} else {
				indicatorInfo.setIsEnable("1");
			}
			return indicatorInfo;
		}
		return indicatorInfo;
	}

}
